#include "mfmenu.hpp"

bool WindowWithMenu::_mouse_move(int x,int y){
    if(y<_menu_height&&enable_top_menu&&!not_top){
        //必定在菜单栏
        int w=0;
        for(auto item=items->begin(),end=items->end();item!=end;item++){
            auto i=*item;
            auto _w=i->_w+10;
            w+=_w;
            if(w>=x){
                if(!i->enabled){
                    return false;
                }
                auto cur=item-items->begin();
                if(cur!=select_item){
                    select_item=cur;
                    if(menu_pressed){
                        extends->clear();
                        cur_list=i->_l;
                        if(!cur_list){
                            return false;
                        }
                        extends->push_back(cur_list);
                        cur_list->_cur=0;
                        cur_list->_on=-1;
                        cur_list->_rect={w-_w,_menu_height,cur_list->_w,(int)cur_list->children->size()*_menu_item_height};
                    }
                }
                return false;
            }
        }
        return false;
    }
    if(!menu_pressed){
        select_item=-1;
        return true;
    }
    for(auto item=extends->rbegin(),end=extends->rend();item!=end;item++){
        auto l=*item;
        auto &r=l->_rect;
        if(r.x<=x&&x<=r.x+r.w&&r.y<=y&&y<=r.y+r.h){
            if(l->level!=extends->size()){
                extends->erase(extends->begin()+l->level,extends->end());
            }
            auto d=(y-r.y)/_menu_item_height;
            l->_on=l->_cur+d;
            if(l->_on>=l->children->size()){
                return false;
            }
            auto v=l->children->operator[](l->_on);
            if(v->_l&&v->enabled){
                cur_list=v->_l;
                extends->push_back(cur_list);
                cur_list->_on=-1;
                cur_list->_cur=0;
                cur_list->_rect={r.x+r.w,r.y+d*_menu_item_height,cur_list->_w,(int)cur_list->children->size()*_menu_item_height};
            }
            return false;
        }
    }
    if(cur_list){
        cur_list->_on=-1;
    }
    return false;
}

bool WindowWithMenu::_mouse_release(int x,int y,int clicks,unsigned char key){
    if(y<_menu_item_height&&enable_top_menu){
        //菜单栏
        int w=0;
        for(auto item=items->begin(),end=items->end();item!=end;item++){
            auto i=*item;
            auto _w=i->_w+10;
            w+=_w;
            if(w>=x){
                if(!i->enabled){
                    return false;
                }
                auto cur=item-items->begin();
                if(cur!=select_item||!menu_pressed){
                    extends->clear();
                    cur_list=i->_l;
                    if(!cur_list){
                        return false;
                    }
                    menu_pressed=true;
                    extends->push_back(cur_list);
                    cur_list->_cur=0;
                    cur_list->_on=-1;
                    cur_list->_rect={_w-_w,_menu_height,cur_list->_w,(int)cur_list->children->size()*_menu_item_height};
                }
                return false;
            }
        }
        return false;
    }
    for(auto item=extends->rbegin(),end=extends->rend();item!=end;item++){
        auto l=*item;
        auto &r=l->_rect;
        if(r.x<=x&&x<=r.x+r.w&&r.y<=y&&y<=r.y+r.h){
            if(l->level!=extends->size()){
                extends->erase(extends->begin()+l->level,extends->end());
            }
            auto d=(y-r.y)/_menu_item_height;
            l->_on=l->_cur+d;
            if(l->_on>=l->children->size()){
                return false;
            }
            auto v=l->children->operator[](l->_on);
            if(!v->enabled||v->_l){
                return false;
            }
            extends->clear();
            menu_pressed=false;
            select_item=-1;
            v->_v=!v->_v;
            v->func(v);
            not_top=false;
            return false;
        }
    }
    extends->clear();
    select_item=-1;
    menu_pressed=false;
    return true;
}
void WindowWithMenu::_draw(){
    auto r=renderer;
    r->SetTarget(NULL);
    auto normal=normal_color,on=on_color,text=text_color,_text=SDL_Color{text.r,text.g,text.b,120};
    r->SetColor(normal);
    r->FillRect(_r);
    r->SetColor(on);
    int w,h;
    SDL_GetWindowSize(window,&w,&h);
    SDL_Rect rect{0,1};
    auto _h=default_font->height();
    rect.h=_h;
    auto hf=_h>>1;
    if(enable_top_menu){
        auto _select=items->begin()+select_item;
        for(auto item=items->begin(),end=items->end();item!=end;item++){
            auto i=*item;
            if(item==_select){
                rect.w=i->_w+10;
                r->FillRect(rect);
                rect.w-=10,rect.x+=5;
                r->DrawTexture(NULL,&rect,i->_t);
                rect.x+=rect.w+10;
            }
            else{
                rect.x+=5;
                rect.w=i->_w;
                r->DrawTexture(NULL,&rect,i->_t);
                rect.x+=rect.w+10;
            }
            if(rect.x>w){
                break;
            }
        }
    }
    for(auto item=extends->begin(),end=extends->end();item!=end;item++){
        auto l=*item;
        auto w=l->_w;
        rect=l->_rect;
        r->SetColor(normal);
        r->FillRect(rect);
        rect.y+=2;
        rect.h=_h;
        for(auto item=l->children->begin(),end=l->children->end(),o=l->children->begin()+l->_on;item!=end;item++){
            auto i=*item;
            auto t=i->_t;
            if(i->enabled){
                SDL_SetTextureAlphaMod(t,255);
            }
            else{
                SDL_SetTextureAlphaMod(t,120);
            }
            if(item==o){
                r->SetColor(on);
                rect.w=w;
                r->FillRect(rect);
                rect.x+=15;
                SDL_QueryTexture(t,NULL,NULL,&rect.w,NULL);
                r->DrawTexture(NULL,&rect,t);
                rect.x-=15;
                if(i->_l){
                    SDL_Point p1{rect.x+w-8,rect.y+2},p2{rect.x+w-5,rect.y+hf};
                    if(i->enabled){
                        r->SetColor(text);
                    }
                    else{
                        r->SetColor(_text);
                    }
                    r->DrawLine(p1,p2);
                    p1.y=rect.y+rect.h-4;
                    r->DrawLine(p1,p2);
                }
                if(i->DrawCheck()&&i->_v){
                    SDL_Point p1{rect.x+4,rect.y+hf+2},p2{rect.x+8,rect.y+hf+4};
                    if(i->enabled){
                        r->SetColor(text);
                    }
                    else{
                        r->SetColor(_text);
                    }
                    r->DrawLine(p1,p2);
                    p1.x+=8;
                    p1.y-=8;
                    r->DrawLine(p1,p2);
                }
                rect.y+=_menu_item_height+2;
                continue;
            }
            rect.x+=15;
            SDL_QueryTexture(t,NULL,NULL,&rect.w,NULL);
            r->DrawTexture(NULL,&rect,t);
            rect.x-=15;
            if(i->_l){
                SDL_Point p1{rect.x+w-8,rect.y+2},p2{rect.x+w-5,rect.y+hf};
                if(i->enabled){
                    r->SetColor(text);
                }
                else{
                    r->SetColor(_text);
                }
                r->DrawLine(p1,p2);
                p1.y=rect.y+rect.h-4;
                r->DrawLine(p1,p2);
            }
            if(i->DrawCheck()&&i->_v){
                SDL_Point p1{rect.x+4,rect.y+hf+2},p2{rect.x+8,rect.y+hf+4};
                if(i->enabled){
                    r->SetColor(text);
                }
                else{
                    r->SetColor(_text);
                }
                r->DrawLine(p1,p2);
                p1.x+=8;
                p1.y-=8;
                r->DrawLine(p1,p2);
            }
            rect.y+=_menu_item_height+2;
        }
    }
    //下拉菜单
}
void Window::OnWindowResize(int w,int h){}
void Window::ActiveMenu(MenuList* l){}
void WindowWithMenu::OnWindowResize(int w,int h){
    _r={0,0,w,_menu_height};
}

WindowWithMenu::WindowWithMenu(const char* icon,const char* title,int w,int h,bool resize,
bool full,bool enable_top_menu,SDL_Color on_color,SDL_Color normal_color,
SDL_Color text_color,SDL_Color back,Window* parent,SDL_BlendMode mode):
Window(icon,title,w,h,resize,full,back,parent,mode){
    not_top=false;
    menu_pressed=false;
    this->enable_top_menu=enable_top_menu;
    this->text_color=text_color;
    this->normal_color=normal_color;
    this->on_color=on_color;
    select_item=-1;
    items=new vector<MenuItem*>();
    cur_list=NULL;
    extends=new vector<MenuList*>();
    _r={0,0,w,_menu_height};
}
WindowWithMenu::~WindowWithMenu(){
    for(auto item=items->begin(),end=items->end();item!=end;item++){
        delete *item;
    }
    delete items;
    delete extends;
}
MenuItem* WindowWithMenu::AddMenuItem(MenuItem* item){
    items->push_back(item);
    return item;
}
void WindowWithMenu::ActiveMenu(MenuList* menu){
    select_item=-1;
    extends->clear();
    extends->push_back(menu);
    cur_list=menu;
    menu_pressed=true;
    not_top=true;
}